#ifndef COMMON_H
#define COMMON_H

#include<stdio.h>
#include<stdint.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<getopt.h>
#include<unistd.h>
#include<fcntl.h>
#include<libgen.h>
#include<fcntl.h>
#include<netdb.h>
#include<errno.h>
#include<sys/time.h>
#include<sys/mman.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/stat.h>
#include<inttypes.h>
#include<endian.h>
#include<byteswap.h>
#include<netinet/in.h>
#include<infiniband/verbs.h>

#include "print.h"

//#define VISDEBUG 1
#define SHMAT_ADDR (void *)(0x0UL)
#define SHMAT_FLAGS (0)
#define GIDX    1
#define IB_PORT 1
/*队列深度*/
#define COUNT 1010
#define MAX_POLL_CQ_TIMEOUT 2000
/*服务端端口*/
#define PORT 18000
#define STATUS_CODE "OK"
#define WRDTH (128)
#define BURST (2)
#define BUFFER_SIZE_512KB (1024 * 512)
#define C_MR_BUFFER_SIZE (WRDTH * BURST * BUFFER_SIZE_512KB) //128M
#define S_MR_BUFFER_SIZE (1024 * 1024 * 1024) //1G
/*rdma上下文结构体定义*/
struct rdma_info {
    struct ibv_context *ctx;
    struct ibv_pd *pd;
    struct ibv_cq *cq;
    struct ibv_mr *mr;
    struct ibv_qp *qp;
    struct ibv_port_attr port_info;
    void *mrbuf;
    uint64_t mrbuf_size;
    pthread_t cq_poller_thread;
};
/*qp相关信息结构体定义*/
struct qp_info {
    int lid;
    int qpn;
    int psn;
    union ibv_gid gid;
};
/*对端mr的信息(起始地址, rkey(远端地址的访问权限))*/
struct mr_info {
    uint64_t remote_addr;
    uint32_t rkey;
};
/*文件相关的信息*/
struct file_info {
    void *mmap_buf;/*文件映射的内存起始地址*/
    FILE *fp;/*文件描述符*/
    char file_name[256];/*文件名称*/
    uint64_t file_size;/*文件大小*/
    uint32_t file_send_num;/*需要发送的次数*/
    uint32_t copy_num;
};
/*外部函数声明*/
int rdma_init();
int client_work(int fd);
int server_work(int fd);
void rdma_destroy();
void* poll_cq(void *arg);
int qp_state_modify();
int get_file_info(char **argv);
int client_socket_init(int *fd);
int get_server_qp_mr_info(int fd);
int get_client_qp_info(int fd);
int server_scoket_init(int *fd);
int post_send_write(struct mr_info remote_mr, int sge_length, int file_send_num);
/*外部变量声明*/
extern char *server_ip;
#endif
